package com.dream52.pms.common;;

import java.io.InputStream;
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

import com.dream52.pms.util.SerializeUtil;
import org.apache.ibatis.cache.Cache;
import org.apache.ibatis.logging.Log;
import org.apache.ibatis.logging.LogFactory;


import redis.clients.jedis.Jedis;
import redis.clients.jedis.exceptions.JedisConnectionException;

public class RedisCache implements Cache {
	private static Log logger = LogFactory.getLog(RedisCache.class);
	private Jedis redisClient = createClient();
	/** The ReadWriteLock. */
	private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
	private static final String REDIS_CONFIG = "/redis.properties";

	private String id;

	public RedisCache(final String id) {
		if (id == null) {
			throw new IllegalArgumentException("Cache instances require an ID");
		}
		System.out.println(">>>>>>>>>>>RedisCache:id=" + id);
		this.id = id;
	}

	public String getId() {
		return this.id;
	}

	public int getSize() {
		Jedis redisClient = createClient();
		Integer result = 0;
		try {
			result= Integer.valueOf(redisClient.dbSize().toString());
		}catch(JedisConnectionException e) {
			e.printStackTrace();
		} finally {
			redisClient.close();
		}

		return result;
	}

	public void putObject(Object key, Object value) {
		if(null==value) {
			return;
		}

		//System.out.println(">>>>>>>>>>>setCache:" + printKey + "=" + value);
		//redisClient.set(SerializeUtil.serialize(key.toString()), SerializeUtil.serialize(value));

		//String printKey = String.valueOf(key);
		//printKey = printKey.substring(printKey.indexOf(":",3)+1);
		Jedis redisClient = createClient();
		try {
			System.out.println(">>>>>>>>>>>setCache:" + key + "=" + value);
			redisClient.hset(id, key.toString(), value.toString());
		}catch(JedisConnectionException e) {
			e.printStackTrace();
		} finally {
			redisClient.close();
		}

	}

	public Object getObject(Object key) {
		//Object value = SerializeUtil.unserialize(redisClient.get(SerializeUtil.serialize(key.toString())));
		//Object value = SerializeUtil.unserialize(redisClient.hget(SerializeUtil.serialize(id),SerializeUtil.serialize(key.toString())));
		Jedis redisClient = createClient();
		Object value = null;
		try {
			value = redisClient.hget(id, key.toString());

			//String printKey = String.valueOf(key);
			//printKey = printKey.substring(printKey.indexOf(":",3)+1);
			//System.out.println(">>>>>>>>>>>getCache:" + printKey + "=" + value);
			System.out.println(">>>>>>>>>>>getCache:" + key + "=" + value);
		}catch(JedisConnectionException e) {
			e.printStackTrace();
		} finally {
			redisClient.close();
		}
		return value;
	}

	public Object removeObject(Object key) {
		//return redisClient.expire(SerializeUtil.serialize(key.toString()), 0);
		Jedis redisClient = createClient();
		Object obj = null;
		try {
			obj = redisClient.del(SerializeUtil.serialize(key.toString()));
			//return redisClient.hdel(id, key.toString());
		}catch(JedisConnectionException e) {
			e.printStackTrace();
		} finally {
			redisClient.close();
		}

		return obj;
	}

	public void clear() {

		Jedis redisClient = createClient();
		try {
			System.out.println("\n>>>>>>>>>>>clearCache:" + id);
			Set<String> setStr = redisClient.hkeys(id);
			if(setStr.size() > 0 ){
				String[] keyArray = setStr.toArray(new String[]{});
				redisClient.hdel(id, keyArray);
			}

		}catch(JedisConnectionException e) {
			e.printStackTrace();
		} finally {
			redisClient.close();
		}


	}

	public void clearAll() {
		Jedis redisClient = createClient();
		try {
			redisClient.flushDB();
		}catch(JedisConnectionException e) {
			e.printStackTrace();
		} finally {
			redisClient.close();
		}
	}

	public ReadWriteLock getReadWriteLock() {
		return readWriteLock;
	}

	protected Jedis createClient() {
		try {
			InputStream insss = RedisCache.class.getResourceAsStream(REDIS_CONFIG);
			Properties pss = new Properties();
			pss.load(insss);

			String address = pss.getProperty("redis.host");
			int  port= Integer.parseInt(pss.getProperty("redis.port"));
			String password = pss.getProperty("redis.password");
			int timeout = Integer.parseInt(pss.getProperty("redis.timeout"));

//            JedisPool pool = new JedisPool(new JedisPoolConfig(),address, port, timeout, password);
//            System.out.println(pool.toString());
//            Jedis jedis=pool.getResource();

			Jedis jedis = new Jedis(address, port);  //指定Redis服务Host和port
			jedis.auth(password);


			return jedis;
		} catch (Exception e) {
			e.printStackTrace();
		}
		throw new RuntimeException("初始化连接池错误");
	}

}